using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Ace.Files;
using Ace;
using System.Windows;
using System.IO;
using System.Windows.Controls.Primitives;
using System.Windows.Media;
using Ace.Files.Json;
using MalwarePatch.Languages;
using System.Globalization;
using System.Diagnostics;

namespace MalwarePatch.Models
{
  sealed class BuiltInCertificates : Certificates
  {
    private BuiltInCertificates(params string[] names)
    {
      foreach (var name in names)
      {
        var data = getCertificateData(name);
        if (data != null)
        {
          certificateFiles.Add(new CertificateFile(data));
        }
        else
        {
          Debug.WriteLine($"Missing certificate data for {name}");
        }
      }
    }

    private static readonly List<BuiltInCertificates> all = new List<BuiltInCertificates>();
    private static BinaryData getCertificateData(string name)
    {
      if (BuildConfig.IsUnbundled)
      {
        var path = Path.Combine("Certificates", name);
        if (!File.Exists(path))
        {
          return null;
        }
        return File.ReadAllBytes(path);
      }
      else
      {
        var uri = new Uri("/Certificates/" + name, UriKind.Relative);
        return AppResource.GetResourceData(uri);
      }
    }
    private static void loadList()
    {
      all.Clear();

      var certificateMap = JsonObject
          .Parse(AppResource
          .GetResourceData("assets/certificate-map.json")
          .ToString(true));

      var displayNameMap = JsonObject
          .Parse(AppResource
          .GetResourceData("assets/display-names.json")
          .ToString(true));

      const string fallbackLanguageTag = "en-US";
      var languageTag = CultureInfo.CurrentUICulture.IetfLanguageTag;

      if (displayNameMap.ContainsName(languageTag))
      {
        displayNameMap = displayNameMap[languageTag].ObjectValue;
      }
      else
      {
        displayNameMap = displayNameMap[fallbackLanguageTag].ObjectValue;
      }

      var maps = from key in certificateMap.Select(p => p.Name)
                 join displayName in displayNameMap
                 on key equals displayName.Name
                 select (
                    certificates: certificateMap[key].ArrayValue.FilterString().ToArray(),
                    displayName: displayName.StringValue
                 );
      foreach (var (certificates, displayName) in maps)
      {
        all.Add(new BuiltInCertificates(certificates) { DisplayName = displayName });
      }
    }
    public static List<BuiltInCertificates> All
    {
      get
      {
        if (all.Count == 0)
        {
          loadList();
        }
        return all;
      }
    }
  }

}